package com.ssy.lingxi.marketing.serviceimpl;

import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.marketing.PlatformCouponTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.PlatformSuitableMemberEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.MemberAndRoleIdVO;
import com.ssy.lingxi.common.model.vo.SelectItemVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.marketing.entity.coupon.CouponGoodsDO;
import com.ssy.lingxi.marketing.entity.coupon.PlatformCouponDO;
import com.ssy.lingxi.marketing.entity.coupon.PlatformCouponDetailDO;
import com.ssy.lingxi.marketing.model.constant.*;
import com.ssy.lingxi.marketing.model.dto.CountCouponDetailDTO;
import com.ssy.lingxi.marketing.model.vo.common.request.CommonAgreeRequest;
import com.ssy.lingxi.marketing.model.vo.common.request.CommonIdReq;
import com.ssy.lingxi.marketing.model.vo.common.request.CommonIdsRequest;
import com.ssy.lingxi.marketing.model.vo.common.response.TaskStepVO;
import com.ssy.lingxi.marketing.model.vo.coupon.request.*;
import com.ssy.lingxi.marketing.model.vo.coupon.response.*;
import com.ssy.lingxi.marketing.repository.*;
import com.ssy.lingxi.marketing.service.IPlatformCouponService;
import com.ssy.lingxi.marketing.service.IProcessFeignService;
import com.ssy.lingxi.marketing.service.IScheduleFeignService;
import com.ssy.lingxi.marketing.service.feign.IMemberFeignService;
import com.ssy.lingxi.marketing.service.feign.IOrderFeignService;
import com.ssy.lingxi.marketing.service.feign.IPlatformManageFeignService;
import com.ssy.lingxi.marketing.serviceimpl.base.coupon.BaseCouponGoodsService;
import com.ssy.lingxi.marketing.serviceimpl.base.coupon.BaseCouponRecordService;
import com.ssy.lingxi.marketing.serviceimpl.base.coupon.BaseCouponRuleService;
import com.ssy.lingxi.marketing.serviceimpl.base.coupon.BasePlatformCouponService;
import com.ssy.lingxi.marketing.serviceimpl.component.SuitableFieldComponent;
import com.ssy.lingxi.marketing.serviceimpl.component.coupon.CouponQueryComponent;
import com.ssy.lingxi.marketing.serviceimpl.component.coupon.CouponReceiveComponent;
import com.ssy.lingxi.marketing.utils.NumberUtil;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignLevelConfigVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignLogoVO;
import com.ssy.lingxi.order.api.model.vo.response.OrderAfterSaleStatusVO;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.ShopVO;
import com.ssy.lingxi.workflow.api.model.contant.ProcessTaskStatusEnum;
import com.ssy.lingxi.workflow.api.model.vo.request.InternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.request.TaskExecuteVO;
import com.ssy.lingxi.workflow.api.model.vo.request.TaskStartVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleProcessDefVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 平台优惠券服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/6/25
 */
@Slf4j
@Service
public class PlatformCouponServiceImpl extends BasePlatformCouponService implements IPlatformCouponService {

    @Resource
    private PlatformCouponRepository platformCouponRepository;
    @Resource
    private PlatformCouponDetailRepository platformCouponDetailRepository;
    @Resource
    private BaseCouponRecordService baseCouponRecordService;
    @Resource
    private IProcessFeignService processFeignService;
    @Resource
    private IOrderFeignService orderFeignService;
    @Resource
    private IMemberFeignService memberFeignService;
    @Resource
    private IPlatformManageFeignService platformManageService;
    @Resource
    private CouponGoodsRepository goodsRepository;
    @Resource
    private CouponMemberLevelRepository memberLevelRepository;
    @Resource
    private CouponShopRepository shopRepository;
    @Resource
    private IScheduleFeignService scheduleFeignService;
    @Resource
    private BaseCouponRuleService baseCouponRuleService;
    @Resource
    private BaseCouponGoodsService baseCouponGoodsService;
    @Resource
    private CouponReceiveComponent couponReceiveComponent;
    @Resource
    private CouponQueryComponent couponQueryComponent;

    @Override
    public Wrapper<PageData<PlatformCouponSummaryPageResponse>> pageSummaryPlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = NumberUtil.notNullOrZero(request.getStatus()) ? Collections.singletonList(request.getStatus()) : Collections.emptyList();
        request.setSortName("releaseTimeStart");
        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        List<PlatformCouponSummaryPageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponSummaryPageResponse response = new PlatformCouponSummaryPageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            response.setUpdate(Arrays.asList(PlatformCouponStatusEnum.WAIT_EXECUTE.getCode(),
                    PlatformCouponStatusEnum.EXECUTING.getCode(),
                    PlatformCouponStatusEnum.STOP.getCode()).contains(coupon.getStatus())
            );
            response.setCancel(PlatformCouponStatusEnum.WAIT_EXECUTE.getCode().equals(coupon.getStatus()));
            response.setStop(PlatformCouponStatusEnum.EXECUTING.getCode().equals(coupon.getStatus()));
            response.setRestart(PlatformCouponStatusEnum.STOP.getCode().equals(coupon.getStatus()));
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<PlatformCouponSubmitAuditPageResponse>> pageSubmitAuditPlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Arrays.asList(
                PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode(),
                PlatformCouponStatusEnum.WAIT_AUDIT_1_REJECT.getCode(),
                PlatformCouponStatusEnum.WAIT_AUDIT_2_REJECT.getCode()
        );
        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        List<PlatformCouponSubmitAuditPageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponSubmitAuditPageResponse response = new PlatformCouponSubmitAuditPageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            response.setSubmit(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode().equals(coupon.getStatus()));
            response.setDelete(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode().equals(coupon.getStatus()));
            response.setUpdate(Arrays.asList(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_1_REJECT.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_2_REJECT.getCode()).contains(coupon.getStatus()));
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<PlatformCouponAuditPageResponse>> pageAuditOnePlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Collections.singletonList(PlatformCouponStatusEnum.WAIT_AUDIT_1.getCode());
        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        List<PlatformCouponAuditPageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponAuditPageResponse response = new PlatformCouponAuditPageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            response.setAudit(PlatformCouponStatusEnum.WAIT_AUDIT_1.getCode().equals(coupon.getStatus()));
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<PlatformCouponAuditPageResponse>> pageAuditTwoPlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Collections.singletonList(PlatformCouponStatusEnum.WAIT_AUDIT_2.getCode());
        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        List<PlatformCouponAuditPageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponAuditPageResponse response = new PlatformCouponAuditPageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            response.setAudit(PlatformCouponStatusEnum.WAIT_AUDIT_2.getCode().equals(coupon.getStatus()));
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<PlatformCouponSubmitPageResponse>> pageSubmitPlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Collections.singletonList(PlatformCouponStatusEnum.WAIT_SUBMIT.getCode());
        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        List<PlatformCouponSubmitPageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponSubmitPageResponse response = new PlatformCouponSubmitPageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            response.setSubmit(PlatformCouponStatusEnum.WAIT_SUBMIT.getCode().equals(coupon.getStatus()));
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<PlatformCouponExecutePageResponse>> pageExecutePlatformCoupon(PlatformCouponPageRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Arrays.asList(PlatformCouponStatusEnum.WAIT_EXECUTE.getCode(),
                PlatformCouponStatusEnum.EXECUTING.getCode(), PlatformCouponStatusEnum.STOP.getCode(),
                PlatformCouponStatusEnum.CANCEL.getCode(), PlatformCouponStatusEnum.FINISH.getCode());

        Page<PlatformCouponDO> pageList = basePagePlatformCoupon(request, statusList, loginUser);
        if (CollectionUtils.isEmpty(pageList.getContent())) {
            return Wrapper.success(new PageData<>(0L, Collections.emptyList()));
        }

        // 统计数量
        List<Long> couponIdList = pageList.stream().map(PlatformCouponDO::getId).collect(Collectors.toList());

        List<CountCouponDetailDTO> countCouponDetailDTOList = couponQueryComponent.countPlatformCouponDetail(couponIdList);
        Map<Long, CountCouponDetailDTO> couponMap = countCouponDetailDTOList.stream().collect(Collectors.toMap(e -> e.getCouponId(), e -> e, (e1, e2) -> e2));

        List<PlatformCouponExecutePageResponse> resultList = pageList.stream().map(coupon -> {
            PlatformCouponExecutePageResponse response = new PlatformCouponExecutePageResponse();
            response.setId(coupon.getId());
            response.setName(coupon.getName());
            response.setType(coupon.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(coupon.getType()));
            response.setReleaseTimeStart(coupon.getReleaseTimeStart());
            response.setReleaseTimeEnd(coupon.getReleaseTimeEnd());
            response.setDenomination(coupon.getDenomination());
            response.setQuantity(coupon.getQuantity());
            response.setGetWay(coupon.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(coupon.getGetWay()));
            response.setEffectiveType(coupon.getEffectiveType());
            response.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            response.setInvalidDay(coupon.getInvalidDay());
            response.setStatus(coupon.getStatus());
            response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(coupon.getStatus()));
            response.setCreateTime(coupon.getCreateTime());
            Integer obtainQuantityNum = Optional.ofNullable(couponMap.get(coupon.getId())).map(CountCouponDetailDTO::getObtainQuantity).orElse(0);
            Integer useQuantityNum = Optional.ofNullable(couponMap.get(coupon.getId())).map(CountCouponDetailDTO::getUseQuantity).orElse(0);
            Integer dueQuantityNum = Optional.ofNullable(couponMap.get(coupon.getId())).map(CountCouponDetailDTO::getDueQuantity).orElse(0);
            response.setObtainQuantity(obtainQuantityNum);
            response.setUseQuantity(useQuantityNum);
            response.setDueQuantity(dueQuantityNum);
            // 状态进行中, 且领取类型为指定会员, 且剩余领取数量大于0
            boolean releaseBtn = PlatformCouponStatusEnum.EXECUTING.getCode().equals(coupon.getStatus())
                    && PlatformCouponGetWayEnum.APPOINT.getCode().equals(coupon.getGetWay())
                    && (coupon.getQuantity() - obtainQuantityNum) > 0;
            response.setRelease(releaseBtn);
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PlatformCouponResponse> getPlatformCoupon(CommonIdReq request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        PlatformCouponResponse response = new PlatformCouponResponse();
        response.setId(platformCouponDO.getId());
        response.setName(platformCouponDO.getName());
        response.setType(platformCouponDO.getType());
        response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(platformCouponDO.getType()));
        response.setReleaseTimeStart(platformCouponDO.getReleaseTimeStart());
        response.setReleaseTimeEnd(platformCouponDO.getReleaseTimeEnd());
        response.setDenomination(platformCouponDO.getDenomination());
        response.setQuantity(platformCouponDO.getQuantity());
        response.setGetWay(platformCouponDO.getGetWay());
        response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(platformCouponDO.getGetWay()));
        response.setConditionGetTotal(platformCouponDO.getConditionGetTotal());
        response.setConditionGetDay(platformCouponDO.getConditionGetDay());
        response.setEffectiveType(platformCouponDO.getEffectiveType());
        response.setEffectiveTimeStart(platformCouponDO.getEffectiveTimeStart());
        response.setEffectiveTimeEnd(platformCouponDO.getEffectiveTimeEnd());
        response.setInvalidDay(platformCouponDO.getInvalidDay());
        response.setUseConditionMoney(platformCouponDO.getUseConditionMoney());
        response.setUseConditionDesc(platformCouponDO.getUseConditionDesc());
        response.setStatus(platformCouponDO.getStatus());
        response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(platformCouponDO.getStatus()));
        response.setSuitableMemberTypes(SuitableFieldComponent.parseCouponSuitableMember(platformCouponDO.getSuitableMember()).stream().map(e -> {
            PlatformSuitableMemberEnum platformSuitableMemberEnum = PlatformSuitableMemberEnum.toEnum(e);
            return new SelectItemVO(platformSuitableMemberEnum.getCode(), platformSuitableMemberEnum.getMessage());
        }).collect(Collectors.toList()));
        response.setMemberTypes(SuitableFieldComponent.parseMarketingMemberType(platformCouponDO.getSuitableMemberType()).stream().map(e -> {
            MemberTypeEnum memberTypeEnum = MemberTypeEnum.toEnum(e);
            return new SelectItemVO(memberTypeEnum.getCode(), memberTypeEnum.getMessage());
        }).collect(Collectors.toList()));
        response.setCreateTime(platformCouponDO.getCreateTime());
        response.setSuitableMemberLevelTypes(baseCouponRuleService.listMemberLevel(BelongTypeEnum.PLATFORM, platformCouponDO.getId()));
        response.setSuitableMallTypes(baseCouponRuleService.listShop(BelongTypeEnum.PLATFORM, platformCouponDO.getId()));

        List<SuitablePlatformCommoditySkuVO> platformCommoditySkuVOS = new ArrayList<>();
        if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(platformCouponDO.getType())) {
            platformCommoditySkuVOS = baseCouponGoodsService.listPlatformCouponGoods(platformCouponDO.getId());
        }
        response.setSuitableCommoditySkuList(platformCommoditySkuVOS);

        // 流转记录
        response.setHistory(baseCouponRecordService.listPlatformCouponRecord(platformCouponDO));

        InternalProcessQueryVO internalProcessQueryVO = new InternalProcessQueryVO();
        internalProcessQueryVO.setProcessKey(MarketingConstants.platform_coupon_key);
        internalProcessQueryVO.setTaskId(platformCouponDO.getTaskId());
        internalProcessQueryVO.setMemberId(platformCouponDO.getMemberId());

        Wrapper<SimpleProcessDefVO> result = processFeignService.findSimpleInternalTaskDefinitions(internalProcessQueryVO);
        if (result.getCode() == ResponseCode.SUCCESS.getCode()) {
            List<SimpleTaskVO> tasks = result.getData().getTasks();
            Integer currentStep = result.getData().getCurrentStep();
            List<TaskStepVO> taskStepVOList = tasks.stream().map(task -> {
                TaskStepVO taskStepVO = new TaskStepVO();
                taskStepVO.setStep(task.getTaskStep());
                taskStepVO.setTaskName(task.getTaskName());
                taskStepVO.setRoleName(task.getRoleName());
                List<Integer> statusList = Arrays.asList(
                        PlatformCouponStatusEnum.WAIT_EXECUTE.getCode(),
                        PlatformCouponStatusEnum.EXECUTING.getCode(),
                        PlatformCouponStatusEnum.STOP.getCode(),
                        PlatformCouponStatusEnum.CANCEL.getCode(),
                        PlatformCouponStatusEnum.FINISH.getCode()
                );
                if (StringUtils.isBlank(platformCouponDO.getTaskId()) && statusList.contains(platformCouponDO.getStatus())) {
                    taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
                } else {
                    taskStepVO.setIsExecute(currentStep >= task.getTaskStep() ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
                }
                return taskStepVO;
            }).collect(Collectors.toList());
            response.setTaskSteps(taskStepVOList);
        }

        return Wrapper.success(response);
    }

    @Override
    public Wrapper<PlatformCouponGrantResponse> getGrantPlatformCoupon(CommonIdReq request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        PlatformCouponGrantResponse response = new PlatformCouponGrantResponse();
        response.setId(platformCouponDO.getId());
        response.setName(platformCouponDO.getName());
        response.setType(platformCouponDO.getType());
        response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(platformCouponDO.getType()));
        response.setReleaseTimeStart(platformCouponDO.getReleaseTimeStart());
        response.setReleaseTimeEnd(platformCouponDO.getReleaseTimeEnd());
        response.setDenomination(platformCouponDO.getDenomination());
        response.setQuantity(platformCouponDO.getQuantity());
        response.setGetWay(platformCouponDO.getGetWay());
        response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(platformCouponDO.getGetWay()));
        response.setConditionGetTotal(platformCouponDO.getConditionGetTotal());
        response.setConditionGetDay(platformCouponDO.getConditionGetDay());
        response.setEffectiveType(platformCouponDO.getEffectiveType());
        response.setEffectiveTimeStart(platformCouponDO.getEffectiveTimeStart());
        response.setEffectiveTimeEnd(platformCouponDO.getEffectiveTimeEnd());
        response.setInvalidDay(platformCouponDO.getInvalidDay());
        response.setUseConditionMoney(platformCouponDO.getUseConditionMoney());
        response.setUseConditionDesc(platformCouponDO.getUseConditionDesc());
        response.setStatus(platformCouponDO.getStatus());
        response.setStatusName(PlatformCouponStatusEnum.getCodeMessage(platformCouponDO.getStatus()));
        response.setCreateTime(platformCouponDO.getCreateTime());
        response.setSuitableMemberLevelTypes(baseCouponRuleService.listMemberLevelId(BelongTypeEnum.PLATFORM, platformCouponDO.getId()));

        List<PlatformCouponDetailDO> detailDOList = platformCouponDetailRepository.findAllByCouponId(platformCouponDO.getId());
        List<MemberAndRoleIdVO> memberList = detailDOList.stream().map(detail -> new MemberAndRoleIdVO(detail.getSubMemberId(), detail.getSubRoleId())).collect(Collectors.toList());
        response.setMemberList(memberList);

        return Wrapper.success(response);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> addPlatformCoupon(PlatformCouponAddRequest request, UserLoginCacheDTO loginUser) {
        Wrapper<Void> checkParamWrapper = this.checkPlatformCouponParam(request);
        if (ResponseCode.SUCCESS.getCode() != checkParamWrapper.getCode()) {
            return Wrapper.fail(checkParamWrapper.getCode(), checkParamWrapper.getMessage());
        }

        // 查询商城数据
        Wrapper<List<ShopVO>> shopWrapper = platformManageService.shopByIdList(request.getSuitableMallTypes());
        if (ResponseCode.SUCCESS.getCode() != shopWrapper.getCode()) {
            return Wrapper.fail(shopWrapper.getCode(), shopWrapper.getMessage());
        }

        // 查询适用会员等级
        List<MemberFeignLevelConfigVO> memberFeignLevelConfigVOList = Collections.emptyList();
        List<Long> memberLevelConfigIds = request.getSuitableMemberLevelTypes();
        if (!CollectionUtils.isEmpty(memberLevelConfigIds)) {
            Wrapper<List<MemberFeignLevelConfigVO>> memberLevelConfigWrapper = memberFeignService.getMemberLevelConfigBatch(memberLevelConfigIds);
            if (ResponseCode.SUCCESS.getCode() != memberLevelConfigWrapper.getCode()) {
                return Wrapper.fail(memberLevelConfigWrapper.getCode(), memberLevelConfigWrapper.getMessage());
            }
            memberFeignLevelConfigVOList = memberLevelConfigWrapper.getData();
        }

        // 商品
        List<SuitablePlatformCommoditySkuVO> suitableCommoditySkuList = new ArrayList<>();
        if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(request.getType())) {
            // 商品只能选择一个
            suitableCommoditySkuList = request.getSuitableCommoditySkuList();
            if (suitableCommoditySkuList.size() > 1) {
                return Wrapper.fail(ResponseCode.MARKETING_COUPON_COMMODITY_MUST_ONE);
            }
        }

        PlatformCouponDO platformCouponDO = new PlatformCouponDO();
        platformCouponDO.setName(request.getName());
        platformCouponDO.setType(request.getType());
        platformCouponDO.setReleaseTimeStart(request.getReleaseTimeStart());
        platformCouponDO.setReleaseTimeEnd(request.getReleaseTimeEnd());
        platformCouponDO.setDenomination(request.getDenomination());
        platformCouponDO.setQuantity(request.getQuantity());
        platformCouponDO.setGetWay(request.getGetWay());
        if (PlatformCouponGetWayEnum.FRONT.getCode().equals(request.getGetWay())) {
            platformCouponDO.setConditionGetTotal(request.getConditionGetTotal());
            platformCouponDO.setConditionGetDay(request.getConditionGetDay());
        }
        platformCouponDO.setEffectiveType(request.getEffectiveType());
        if (PlatformCouponEffectiveTypeEnum.FIXED.getCode().equals(request.getEffectiveType())) {
            platformCouponDO.setEffectiveTimeStart(request.getEffectiveTimeStart());
            platformCouponDO.setEffectiveTimeEnd(request.getEffectiveTimeEnd());
        } else {
            platformCouponDO.setInvalidDay(request.getInvalidDay());
        }
        platformCouponDO.setUseConditionMoney(request.getUseConditionMoney());
        platformCouponDO.setUseConditionDesc(request.getUseConditionDesc());
        platformCouponDO.setSuitableMember(SuitableFieldComponent.generateCouponSuitableMember(request.getSuitableMemberTypes()));
        platformCouponDO.setSuitableMemberType(SuitableFieldComponent.generateCouponMemberType(request.getMemberTypes()));
        platformCouponDO.setMemberId(loginUser.getMemberId());
        platformCouponDO.setRoleId(loginUser.getMemberRoleId());
        platformCouponDO.setMemberName(loginUser.getCompany());
        platformCouponDO.setCreateTime(System.currentTimeMillis());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        // 会员等级
        baseCouponRuleService.saveMemberLevel(BelongTypeEnum.PLATFORM, platformCouponDO.getId(), memberFeignLevelConfigVOList);
        // 商城
        baseCouponRuleService.saveShop(BelongTypeEnum.PLATFORM, platformCouponDO.getId(), shopWrapper.getData());

        // 商品
        if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(request.getType())) {
            baseCouponGoodsService.savePlatformCouponGoods(loginUser, platformCouponDO.getId(), suitableCommoditySkuList);
        }

        TaskStartVO taskStartVO = new TaskStartVO();
        taskStartVO.setProcessKey(MarketingConstants.platform_coupon_key);
        taskStartVO.setMemberId(loginUser.getMemberId());
        taskStartVO.setRoleId(loginUser.getMemberRoleId());
        taskStartVO.setDataId(platformCouponDO.getId());

        Wrapper<SimpleTaskCompleteVO> result = processFeignService.startSimpleProcess(taskStartVO);
        if (result.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("平台优惠券新增, 调用工作流失败: {}", result.getMessage());
            throw new BusinessException(ResponseCode.SERVICE_WORKFLOW_ERROR);
        }

        platformCouponDO.setStatus(result.getData().getStatus());
        platformCouponDO.setTaskId(result.getData().getTaskId());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updatePlatformCoupon(PlatformCouponUpdateRequest request, UserLoginCacheDTO loginUser) {
        Wrapper<Void> checkParamWrapper = this.checkPlatformCouponParam(request);
        if (ResponseCode.SUCCESS.getCode() != checkParamWrapper.getCode()) {
            return Wrapper.fail(checkParamWrapper.getCode(), checkParamWrapper.getMessage());
        }

        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        // 校验状态
        List<Integer> statusList = Arrays.asList(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_1_REJECT.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_2_REJECT.getCode());
        if (!statusList.contains(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 查询商城数据
        Wrapper<List<ShopVO>> shopWrapper = platformManageService.shopByIdList(request.getSuitableMallTypes());
        if (ResponseCode.SUCCESS.getCode() != shopWrapper.getCode()) {
            return Wrapper.fail(shopWrapper.getCode(), shopWrapper.getMessage());
        }

        // 查询适用会员等级
        List<MemberFeignLevelConfigVO> memberFeignLevelConfigVOList = Collections.emptyList();
        List<Long> memberLevelConfigIds = request.getSuitableMemberLevelTypes();
        if (!CollectionUtils.isEmpty(memberLevelConfigIds)) {
            Wrapper<List<MemberFeignLevelConfigVO>> memberLevelConfigWrapper = memberFeignService.getMemberLevelConfigBatch(request.getSuitableMemberLevelTypes());
            if (ResponseCode.SUCCESS.getCode() != memberLevelConfigWrapper.getCode()) {
                return Wrapper.fail(memberLevelConfigWrapper.getCode(), memberLevelConfigWrapper.getMessage());
            }
            memberFeignLevelConfigVOList = memberLevelConfigWrapper.getData();
        }


        // 商品
        List<SuitablePlatformCommoditySkuVO> suitableCommoditySkuList = new ArrayList<>();
        if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(request.getType())) {
            // 商品只能选择一个
            suitableCommoditySkuList = request.getSuitableCommoditySkuList();
            if (suitableCommoditySkuList.size() > 1) {
                return Wrapper.fail(ResponseCode.MARKETING_COUPON_COMMODITY_MUST_ONE);
            }
        }

        // 拒绝状态修改后为待提交
        List<Integer> rejectStatusList = Arrays.asList(PlatformCouponStatusEnum.WAIT_AUDIT_1_REJECT.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_2_REJECT.getCode());
        if (rejectStatusList.contains(platformCouponDO.getStatus())) {
            platformCouponDO.setStatus(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode());
        }

        platformCouponDO.setName(request.getName());
        platformCouponDO.setType(request.getType());
        platformCouponDO.setReleaseTimeStart(request.getReleaseTimeStart());
        platformCouponDO.setReleaseTimeEnd(request.getReleaseTimeEnd());
        platformCouponDO.setDenomination(request.getDenomination());
        platformCouponDO.setQuantity(request.getQuantity());
        platformCouponDO.setGetWay(request.getGetWay());
        if (PlatformCouponGetWayEnum.FRONT.getCode().equals(request.getGetWay())) {
            platformCouponDO.setConditionGetTotal(request.getConditionGetTotal());
            platformCouponDO.setConditionGetDay(request.getConditionGetDay());
        } else {
            platformCouponDO.setConditionGetTotal(null);
            platformCouponDO.setConditionGetDay(null);
        }
        platformCouponDO.setEffectiveType(request.getEffectiveType());
        if (PlatformCouponEffectiveTypeEnum.FIXED.getCode().equals(request.getEffectiveType())) {
            platformCouponDO.setEffectiveTimeStart(request.getEffectiveTimeStart());
            platformCouponDO.setEffectiveTimeEnd(request.getEffectiveTimeEnd());
            platformCouponDO.setInvalidDay(null);
        } else {
            platformCouponDO.setInvalidDay(request.getInvalidDay());
            platformCouponDO.setEffectiveTimeStart(null);
            platformCouponDO.setEffectiveTimeEnd(null);
        }
        platformCouponDO.setUseConditionMoney(request.getUseConditionMoney());
        platformCouponDO.setUseConditionDesc(request.getUseConditionDesc());
        platformCouponDO.setSuitableMember(SuitableFieldComponent.generateCouponSuitableMember(request.getSuitableMemberTypes()));
        platformCouponDO.setSuitableMemberType(SuitableFieldComponent.generateCouponMemberType(request.getMemberTypes()));
        if (Arrays.asList(PlatformCouponStatusEnum.WAIT_AUDIT_1.getCode(), PlatformCouponStatusEnum.WAIT_AUDIT_2.getCode()).contains(platformCouponDO.getStatus())) {
            platformCouponDO.setStatus(PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode());
        }

        // 会员等级
        baseCouponRuleService.existsAndDeleteMemberLevel(BelongTypeEnum.PLATFORM, platformCouponDO.getId());
        baseCouponRuleService.saveMemberLevel(BelongTypeEnum.PLATFORM, platformCouponDO.getId(), memberFeignLevelConfigVOList);
        // 商城
        baseCouponRuleService.deleteShop(BelongTypeEnum.PLATFORM, platformCouponDO.getId());
        baseCouponRuleService.saveShop(BelongTypeEnum.PLATFORM, platformCouponDO.getId(), shopWrapper.getData());

        // 商品
        baseCouponGoodsService.existsAndDeleteCouponGoods(BelongTypeEnum.PLATFORM, platformCouponDO.getId());
        if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(request.getType())) {
            baseCouponGoodsService.existsAndDeleteCouponGoods(BelongTypeEnum.PLATFORM, platformCouponDO.getId());
            baseCouponGoodsService.savePlatformCouponGoods(loginUser, platformCouponDO.getId(), suitableCommoditySkuList);
        }

        platformCouponRepository.saveAndFlush(platformCouponDO);
        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> deletePlatformCoupon(CommonIdsRequest request, UserLoginCacheDTO loginUser) {
        List<PlatformCouponDO> platformCouponDOList = platformCouponRepository.findAllById(request.getIds());
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (!PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode().equals(platformCouponDO.getStatus())) {
                return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
        }

        // 删除商城
        shopRepository.deleteByBelongTypeAndCouponIdIn(BelongTypeEnum.PLATFORM.getCode(), request.getIds());
        // 删除会员等级
        memberLevelRepository.deleteByBelongTypeAndCouponIdIn(BelongTypeEnum.PLATFORM.getCode(), request.getIds());
        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode().equals(platformCouponDO.getType())) {
                goodsRepository.deleteByBelongTypeAndCouponId(BelongTypeEnum.PLATFORM.getCode(), platformCouponDO.getId());
            }
        }

        platformCouponRepository.deleteAll(platformCouponDOList);

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> submitAuditPlatformCoupon(CommonIdsRequest request, UserLoginCacheDTO loginUser) {
        List<PlatformCouponDO> platformCouponDOList = platformCouponRepository.findAllById(request.getIds());
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        List<PlatformCouponDO> updateList = new ArrayList<>();
        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
                return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
            }
            if (!PlatformCouponStatusEnum.WAIT_SUBMIT_AUDIT.getCode().equals(platformCouponDO.getStatus())) {
                continue;
            }
            updateList.add(platformCouponDO);
        }

        for (PlatformCouponDO platformCouponDO : updateList) {
            TaskExecuteVO executeVO = new TaskExecuteVO();
            executeVO.setProcessKey(MarketingConstants.platform_coupon_key);
            executeVO.setTaskId(platformCouponDO.getTaskId());
            executeVO.setMemberId(loginUser.getMemberId());
            executeVO.setRoleId(loginUser.getMemberRoleId());
            executeVO.setAgree(ProcessTaskStatusEnum.GOTO_NEXT_STEP.getCode());
            executeVO.setDataId(platformCouponDO.getId());

            // 工作流
            Wrapper<SimpleTaskCompleteVO> result = processFeignService.completeSimpleTask(executeVO);
            if (result.getCode() != ResponseCode.SUCCESS.getCode()) {
                log.error("平台优惠券提交审核,调用工作流失败: {}", result.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_WORKFLOW_ERROR);
            }

            platformCouponDO.setStatus(result.getData().getStatus());
            platformCouponDO.setTaskId(result.getData().getTaskId());
            platformCouponRepository.saveAndFlush(platformCouponDO);

            // 流转记录
            Integer status = result.getData().getStatus();
            baseCouponRecordService.savePlatformCouponRecord(loginUser, platformCouponDO, CouponStrOperateEnum.pt_inner_add.getMessage(), status, PlatformCouponStatusEnum.getCodeMessage(status));
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> auditOnePlatformCoupon(CommonAgreeRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!PlatformCouponStatusEnum.WAIT_AUDIT_1.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        this.baseAuditOnePlatformCoupon(loginUser, Collections.singletonList(platformCouponDO), request.getAgree(), request.getReason());

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> batchAuditOnePlatformCoupon(CommonIdsRequest request, UserLoginCacheDTO loginUser) {
        List<PlatformCouponDO> platformCouponDOList = platformCouponRepository.findAllById(request.getIds());
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
                return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
            }
            if (!PlatformCouponStatusEnum.WAIT_AUDIT_1.getCode().equals(platformCouponDO.getStatus())) {
                return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
        }

        this.baseAuditOnePlatformCoupon(loginUser, platformCouponDOList, ProcessTaskStatusEnum.AGREE.getCode(), "");

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> auditTwoPlatformCoupon(CommonAgreeRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!PlatformCouponStatusEnum.WAIT_AUDIT_2.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        this.baseAuditTwoPlatformCoupon(loginUser, Collections.singletonList(platformCouponDO), request.getAgree(), request.getReason());

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> batchAuditTwoPlatformCoupon(CommonIdsRequest request, UserLoginCacheDTO loginUser) {
        List<PlatformCouponDO> platformCouponDOList = platformCouponRepository.findAllById(request.getIds());
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
                return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
            }
            if (!PlatformCouponStatusEnum.WAIT_AUDIT_2.getCode().equals(platformCouponDO.getStatus())) {
                return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
        }

        this.baseAuditTwoPlatformCoupon(loginUser, platformCouponDOList, ProcessTaskStatusEnum.AGREE.getCode(), "");

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> submitPlatformCoupon(CommonIdsRequest request, UserLoginCacheDTO loginUser) {
        List<PlatformCouponDO> platformCouponDOList = platformCouponRepository.findAllById(request.getIds());
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
                return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
            }
            if (!PlatformCouponStatusEnum.WAIT_SUBMIT.getCode().equals(platformCouponDO.getStatus())) {
                return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
        }

        this.baseSubmitPlatformCoupon(loginUser, platformCouponDOList);

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> grantPlatformCoupon(PlatformCouponGrantRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }
        //填充会员名称
        List<Long> memberIds = request.getGrantMembers().stream().map(o -> o.getSubMemberId()).distinct().collect(Collectors.toList());
        Wrapper<List<MemberFeignLogoVO>> memberLogos = memberFeignService.getMemberLogos(memberIds);
        if(memberLogos.getCode()==ResponseCode.SUCCESS.getCode()&&!CollectionUtils.isEmpty(memberLogos.getData())){
            List<MemberFeignLogoVO> memberLogosData = memberLogos.getData();
            for(PlatformCouponGrantMemberRequest memberRequest :request.getGrantMembers()){
                for(MemberFeignLogoVO member :memberLogosData){
                    if(memberRequest.getSubMemberId().equals(member.getMemberId())){
                        memberRequest.setSubMemberName(member.getName());
                    }
                }
            }
        }
        Wrapper<Void> platformCouponWrapper = couponReceiveComponent.grantPlatformCoupon(platformCouponDO, request.getGrantMembers());
        if (ResponseCode.SUCCESS.getCode() != platformCouponWrapper.getCode()) {
            return Wrapper.fail(platformCouponWrapper.getCode(), platformCouponWrapper.getMessage());
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> modificationPlatformCoupon(PlatformCouponModificationRequest request, UserLoginCacheDTO loginUser) {
        long currentTimeMillis = System.currentTimeMillis();
        // 发放时间
        Wrapper<Void> checkReleaseTimeWrapper = this.checkReleaseTime(currentTimeMillis, request.getReleaseTimeStart(), request.getReleaseTimeEnd());
        if (ResponseCode.SUCCESS.getCode() != checkReleaseTimeWrapper.getCode()) {
            return checkReleaseTimeWrapper;
        }

        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        // 发券数量只能修改多, 不能修改少
        if (platformCouponDO.getQuantity() > request.getQuantity()) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_QUANTITY_GRATER_THEN_OLD_ERROR);
        }

        List<Integer> statusList = Arrays.asList(PlatformCouponStatusEnum.WAIT_EXECUTE.getCode(), PlatformCouponStatusEnum.EXECUTING.getCode(), PlatformCouponStatusEnum.STOP.getCode());
        if (!statusList.contains(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        platformCouponDO.setStatus(PlatformCouponStatusEnum.WAIT_EXECUTE.getCode());
        platformCouponDO.setReleaseTimeStart(request.getReleaseTimeStart());
        platformCouponDO.setReleaseTimeEnd(request.getReleaseTimeEnd());
        platformCouponDO.setQuantity(request.getQuantity());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        // 状态
        if (request.getReleaseTimeStart() > currentTimeMillis) {
            // 定时发券开始
            scheduleFeignService.createPfCouponReleaseStartTask(loginUser, platformCouponDO);

            // 定时发券结束
            scheduleFeignService.createPfCouponReleaseEndTask(loginUser, platformCouponDO);
        } else if (request.getReleaseTimeStart() <= currentTimeMillis
                && request.getReleaseTimeEnd() >= currentTimeMillis) {

            platformCouponDO.setStatus(PlatformCouponStatusEnum.EXECUTING.getCode());
            platformCouponRepository.saveAndFlush(platformCouponDO);

            // 定时发券结束
            scheduleFeignService.createPfCouponReleaseEndTask(loginUser, platformCouponDO);
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> stopPlatformCoupon(PlatformCouponOperationRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!PlatformCouponStatusEnum.EXECUTING.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        platformCouponDO.setStatus(PlatformCouponStatusEnum.STOP.getCode());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        // 流转记录
        baseCouponRecordService.savePlatformCouponRecord(loginUser, platformCouponDO, CouponStrOperateEnum.pt_inner_stop.getMessage(), PlatformCouponStatusEnum.STOP.getCode(), PlatformCouponStatusEnum.STOP.getMessage());

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> restartPlatformCoupon(PlatformCouponOperationRequest request, UserLoginCacheDTO loginUser) {
        long currentTimeMillis = System.currentTimeMillis();
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (currentTimeMillis >= platformCouponDO.getReleaseTimeEnd()) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_RELEASE_START_TIME_ERROR);
        }

        if (!PlatformCouponStatusEnum.STOP.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        platformCouponDO.setStatus(PlatformCouponStatusEnum.EXECUTING.getCode());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        // 流转记录
        baseCouponRecordService.savePlatformCouponRecord(loginUser, platformCouponDO, CouponStrOperateEnum.pt_inner_start.getMessage(), PlatformCouponStatusEnum.EXECUTING.getCode(), PlatformCouponStatusEnum.EXECUTING.getMessage());

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> cancelPlatformCoupon(PlatformCouponOperationRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!PlatformCouponStatusEnum.WAIT_EXECUTE.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        platformCouponDO.setStatus(PlatformCouponStatusEnum.CANCEL.getCode());
        platformCouponRepository.saveAndFlush(platformCouponDO);

        // 流转记录
        baseCouponRecordService.savePlatformCouponRecord(loginUser, platformCouponDO, CouponStrOperateEnum.pt_inner_cancel.getMessage(), PlatformCouponStatusEnum.CANCEL.getCode(), PlatformCouponStatusEnum.CANCEL.getMessage());

        return Wrapper.success();
    }

    @Override
    public Wrapper<PlatformCouponDetailConditionResponse> getExecutePlatformCouponDetailCondition(CommonIdReq request) {
        PlatformCouponDetailConditionResponse response = new PlatformCouponDetailConditionResponse();

        // 商城下拉框
        Wrapper<List<ShopVO>> listWrapper = platformManageService.shopAll();
        if (ResponseCode.SUCCESS.getCode() == listWrapper.getCode()) {
            List<SelectItemVO> shopIdList = listWrapper.getData().stream().map(shop -> new SelectItemVO(shop.getId().intValue(), shop.getName())).collect(Collectors.toList());
            response.setShopList(shopIdList);
        }

        // 适用会员下拉框
        List<SelectItemVO> suitableMemberTypeList = Stream.of(PlatformSuitableMemberEnum.values()).map(ageType -> new SelectItemVO(ageType.getCode(), ageType.getMessage())).collect(Collectors.toList());
        response.setSuitableMemberTypeList(suitableMemberTypeList);

        // 券状态下拉框
        List<SelectItemVO> statusList = Stream.of(PlatformCouponDetailStatusEnum.values()).map(ageType -> new SelectItemVO(ageType.getCode(), ageType.getMessage())).collect(Collectors.toList());
        response.setStatusList(statusList);

        return Wrapper.success(response);
    }

    @Override
    public Wrapper<PageData<PlatformCouponDetailPageResponse>> pageExecutePlatformCouponDetail(PlatformCouponDetailPageRequest request, UserLoginCacheDTO loginUser) {
        PlatformCouponDO platformCouponDO = platformCouponRepository.findById(request.getCouponId()).orElse(null);
        if (Objects.isNull(platformCouponDO)) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        if (!isBelongCurrentMember(loginUser, platformCouponDO.getMemberId(), platformCouponDO.getRoleId())) {
            return Wrapper.fail(ResponseCode.MARKETING_RECORDS_DONT_EXIST);
        }

        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("id").descending());
        Page<PlatformCouponDetailDO> pageList = platformCouponDetailRepository.findAll((Specification<PlatformCouponDetailDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();

            predicateList.add(cb.equal(root.get("coupon").get("id"), request.getCouponId()));

            if (StringUtils.isNotEmpty(request.getCode())) {
                predicateList.add(cb.equal(root.get("code"), request.getCode()));
            }

            if (Objects.nonNull(request.getStatus())) {
                predicateList.add(cb.equal(root.get("status"), request.getStatus()));
            }

            if (Objects.nonNull(request.getCreateTimeStart())) {
                predicateList.add(cb.greaterThanOrEqualTo(root.get("createTime"), request.getCreateTimeStart()));
            }

            if (Objects.nonNull(request.getCreateTimeEnd())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("createTime"), request.getCreateTimeEnd()));
            }

            if (StringUtils.isNotEmpty(request.getMemberName())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("subMemberName"), request.getMemberName()));
            }

            if (Objects.nonNull(request.getSuitableMemberType())) {
                predicateList.add(cb.equal(root.get("suitableMemberType"), request.getSuitableMemberType()));
            }

            if (Objects.nonNull(request.getUseTimeStart())) {
                predicateList.add(cb.greaterThanOrEqualTo(root.get("useTime"), request.getUseTimeStart()));
            }

            if (Objects.nonNull(request.getUseTimeEnd())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("useTime"), request.getUseTimeEnd()));
            }

            if (Objects.nonNull(request.getOrderNo())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("orderNo"), request.getOrderNo()));
            }

            if (Objects.nonNull(request.getShopId())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("shopId"), request.getShopId()));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }, page);

        //查询订单状态
        List<String> orderNoList = pageList.stream().map(o -> o.getOrderNo()).distinct().collect(Collectors.toList());
        Map<String, OrderAfterSaleStatusVO> orderInfoMap = orderFeignService.getOrderInfoMap(orderNoList);

        List<PlatformCouponDetailPageResponse> resultList = pageList.stream().map(detail -> {
            PlatformCouponDetailPageResponse response = new PlatformCouponDetailPageResponse();
            response.setId(detail.getId());
            response.setPlatformCouponId(detail.getCoupon().getId());
            response.setCode(detail.getCode());
            response.setStatus(detail.getStatus());
            response.setStatusName(PlatformCouponDetailStatusEnum.getCodeMessage(detail.getStatus()));
            response.setSubMemberId(detail.getSubMemberId());
            response.setSubRoleId(detail.getSubRoleId());
            response.setSubMemberName(detail.getSubMemberName());
            response.setSuitableMemberTypeName(PlatformSuitableMemberEnum.getCodeMessage(detail.getSuitableMemberType()));
            response.setCreateTime(detail.getCreateTime());
            response.setValidTimeStart(detail.getValidTimeStart());
            response.setValidTimeEnd(detail.getValidTimeEnd());
            response.setOrderNo(detail.getOrderNo());
            response.setUseTime(detail.getUseTime());
            response.setShopName(detail.getShopName());
            response.setAmount(detail.getAmount());
            response.setBuyerMemberName(detail.getBuyerMemberName());
            //填充订单状态
            if(orderInfoMap!=null){
                OrderAfterSaleStatusVO orderAfterSaleStatusVO = orderInfoMap.get(detail.getOrderNo());
                if(orderAfterSaleStatusVO!=null){
                    response.setOrderStatusName(orderAfterSaleStatusVO.getOuterStatusName());
                }
            }
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<ActivityGoodsCouponResponse>> selectSubsidiaryCouponList(ActivityPlatformCouponRequest request, UserLoginCacheDTO loginUser) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("releaseTimeStart").descending());
        Page<PlatformCouponDO> pageList = platformCouponRepository.findAll((Specification<PlatformCouponDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();

            predicateList.add(cb.equal(root.get("type"), PlatformCouponTypeEnum.COMMON.getCode()));

            if (Objects.nonNull(request.getId())) {
                predicateList.add(cb.equal(root.get("id"), request.getId()));
            }

            if (Objects.nonNull(request.getName())) {
                predicateList.add(cb.equal(root.get("name"), request.getName()));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }, page);

        List<ActivityGoodsCouponResponse> resultList = pageList.stream().map(e -> {
            ActivityGoodsCouponResponse response = new ActivityGoodsCouponResponse();
            response.setId(e.getId());
            response.setName(e.getName());
            response.setType(e.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(e.getType()));
            response.setDenomination(e.getDenomination());
            response.setGetWay(e.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(e.getGetWay()));
            response.setUseConditionMoney(e.getUseConditionMoney());
            response.setEffectiveType(e.getEffectiveType());
            response.setEffectiveTypeName(PlatformCouponEffectiveTypeEnum.getCodeMessage(e.getEffectiveType()));
            response.setEffectiveTimeStart(e.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(e.getEffectiveTimeEnd());
            response.setInvalidDay(e.getInvalidDay());
            response.setCreateTime(e.getCreateTime());
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<ActivityPrizeCouponResponse>> selectPrizeCouponList(ActivityPlatformCouponRequest request, UserLoginCacheDTO loginUser) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("releaseTimeStart").descending());
        Page<PlatformCouponDO> pageList = platformCouponRepository.findAll((Specification<PlatformCouponDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();

            // 0元抵扣券
            predicateList.add(cb.equal(root.get("type"), PlatformCouponTypeEnum.ZERO_DISCOUNT.getCode()));

            if (Objects.nonNull(request.getId())) {
                predicateList.add(cb.equal(root.get("id"), request.getId()));
            }

            if (Objects.nonNull(request.getName())) {
                predicateList.add(cb.equal(root.get("name"), request.getName()));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }, page);

        // 适用商品
        List<Long> couponIds = pageList.stream().map(PlatformCouponDO::getId).collect(Collectors.toList());
        List<CouponGoodsDO> goodsDOList = goodsRepository.findAllByBelongTypeAndCouponIdIn(BelongTypeEnum.PLATFORM.getCode(), couponIds);
        Map<Long, List<CouponGoodsDO>> couponGoodsDOMap = goodsDOList.stream().collect(Collectors.groupingBy(CouponGoodsDO::getCouponId));

        List<ActivityPrizeCouponResponse> resultList = pageList.stream().map(e -> {
            ActivityPrizeCouponResponse response = new ActivityPrizeCouponResponse();
            response.setId(e.getId());
            response.setName(e.getName());
            response.setType(e.getType());
            response.setTypeName(PlatformCouponTypeEnum.getCodeMessage(e.getType()));
            response.setDenomination(e.getDenomination());
            response.setGetWay(e.getGetWay());
            response.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(e.getGetWay()));
            response.setUseConditionMoney(e.getUseConditionMoney());
            response.setEffectiveType(e.getEffectiveType());
            response.setEffectiveTypeName(PlatformCouponEffectiveTypeEnum.getCodeMessage(e.getEffectiveType()));
            response.setEffectiveTimeStart(e.getEffectiveTimeStart());
            response.setEffectiveTimeEnd(e.getEffectiveTimeEnd());
            response.setInvalidDay(e.getInvalidDay());
            response.setCreateTime(e.getCreateTime());

            CouponGoodsDO couponGoodsDO = Optional.ofNullable(couponGoodsDOMap.get(e.getId())).map(list -> list.get(0)).orElse(null);
            if (Objects.nonNull(couponGoodsDO)) {
                SuitableProductVO suitableProductVO = new SuitableProductVO();
                suitableProductVO.setProductId(couponGoodsDO.getProductId());
                suitableProductVO.setSkuId(couponGoodsDO.getSkuId());
                suitableProductVO.setProductName(couponGoodsDO.getProductName());
                suitableProductVO.setType(couponGoodsDO.getType());
                suitableProductVO.setCategory(couponGoodsDO.getCategory());
                suitableProductVO.setBrand(couponGoodsDO.getBrand());
                suitableProductVO.setUnit(couponGoodsDO.getUnit());
                suitableProductVO.setPrice(couponGoodsDO.getPrice());
                suitableProductVO.setProductImgUrl(couponGoodsDO.getProductImgUrl());
                response.setSuitableProduct(suitableProductVO);
            }

            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }
}
